#include "aodv_packet.h"
#include <string.h>
#include <stdio.h>

// 辅助函数：将结构体复制到缓冲区
static int serialize(void *dest, const void *src, size_t size, int *offset) {
    memcpy((char *)dest + *offset, src, size);
    *offset += size;
    return 0;
}

// 辅助函数：从缓冲区复制到结构体
static int deserialize(void *dest, const void *src, size_t size, int *offset) {
    memcpy(dest, (const char *)src + *offset, size);
    *offset += size;
    return 0;
}

// 构建RREQ数据包
int build_rreq_packet(aodv_rreq *rreq, uint32_t rreq_id, uint32_t dest_addr, uint32_t dest_seq_num, uint32_t orig_addr, uint32_t orig_seq_num, uint8_t hop_count) {
    if (!rreq) return -1;

    rreq->header.type = AODV_RREQ;
    rreq->rreq_id = rreq_id;
    rreq->dest_addr = dest_addr;
    rreq->dest_seq_num = dest_seq_num;
    rreq->orig_addr = orig_addr;
    rreq->orig_seq_num = orig_seq_num;
    rreq->hop_count = hop_count;

    return 0;
}

// 解析RREQ数据包
int parse_rreq_packet(const void *buffer, int len, aodv_rreq *rreq) {
    if (!buffer || !rreq || len < sizeof(aodv_rreq)) return -1;

    int offset = 0;
    deserialize(&rreq->header.type, buffer, sizeof(aodv_msg_type), &offset);
    if (rreq->header.type != AODV_RREQ) return -1; // 类型不匹配

    deserialize(&rreq->rreq_id, buffer, sizeof(uint32_t), &offset);
    deserialize(&rreq->dest_addr, buffer, sizeof(uint32_t), &offset);
    deserialize(&rreq->dest_seq_num, buffer, sizeof(uint32_t), &offset);
    deserialize(&rreq->orig_addr, buffer, sizeof(uint32_t), &offset);
    deserialize(&rreq->orig_seq_num, buffer, sizeof(uint32_t), &offset);
    deserialize(&rreq->hop_count, buffer, sizeof(uint8_t), &offset);

    return 0;
}

// 构建RREP数据包
int build_rrep_packet(aodv_rrep *rrep, uint32_t dest_addr, uint32_t dest_seq_num, uint32_t orig_addr, uint32_t orig_seq_num, uint8_t hop_count, uint32_t lifetime) {
    if (!rrep) return -1;

    rrep->header.type = AODV_RREP;
    rrep->dest_addr = dest_addr;
    rrep->dest_seq_num = dest_seq_num;
    rrep->orig_addr = orig_addr;
    rrep->orig_seq_num = orig_seq_num;
    rrep->hop_count = hop_count;
    rrep->lifetime = lifetime;

    return 0;
}

// 解析RREP数据包
int parse_rrep_packet(const void *buffer, int len, aodv_rrep *rrep) {
    if (!buffer || !rrep || len < sizeof(aodv_rrep)) return -1;

    int offset = 0;
    deserialize(&rrep->header.type, buffer, sizeof(aodv_msg_type), &offset);
    if (rrep->header.type != AODV_RREP) return -1; // 类型不匹配

    deserialize(&rrep->dest_addr, buffer, sizeof(uint32_t), &offset);
    deserialize(&rrep->dest_seq_num, buffer, sizeof(uint32_t), &offset);
    deserialize(&rrep->orig_addr, buffer, sizeof(uint32_t), &offset);
    deserialize(&rrep->orig_seq_num, buffer, sizeof(uint32_t), &offset);
    deserialize(&rrep->hop_count, buffer, sizeof(uint8_t), &offset);
    deserialize(&rrep->lifetime, buffer, sizeof(uint32_t), &offset);

    return 0;
}

// 构建RERR数据包
int build_rerr_packet(aodv_rerr *rerr, uint8_t dest_count, const uint32_t *unreachable_addrs, const uint32_t *unreachable_seq_nums) {
    if (!rerr) return -1;

    rerr->header.type = AODV_RERR;
    rerr->dest_count = dest_count;
    // 实际实现需要将unreachable_addrs和unreachable_seq_nums复制到缓冲区
    // 这里只是一个占位符，实际需要根据dest_count动态分配内存并复制数据
    // 例如：memcpy(buffer + offset, unreachable_addrs, dest_count * sizeof(uint32_t));
    //       offset += dest_count * sizeof(uint32_t);
    //       memcpy(buffer + offset, unreachable_seq_nums, dest_count * sizeof(uint32_t));

    return 0;
}

// 解析RERR数据包
int parse_rerr_packet(const void *buffer, int len, aodv_rerr *rerr, uint32_t *unreachable_addrs, uint32_t *unreachable_seq_nums) {
    if (!buffer || !rerr || len < sizeof(aodv_header) + sizeof(uint8_t)) return -1;

    int offset = 0;
    deserialize(&rerr->header.type, buffer, sizeof(aodv_msg_type), &offset);
    if (rerr->header.type != AODV_RERR) return -1; // 类型不匹配

    deserialize(&rerr->dest_count, buffer, sizeof(uint8_t), &offset);
    // 实际实现需要从缓冲区读取unreachable_addrs和unreachable_seq_nums
    // 例如：deserialize(unreachable_addrs, buffer, rerr->dest_count * sizeof(uint32_t), &offset);
    //       deserialize(unreachable_seq_nums, buffer, rerr->dest_count * sizeof(uint32_t), &offset);

    return 0;
}

// 构建Hello数据包
int build_hello_packet(aodv_hello *hello, uint32_t lifetime) {
    if (!hello) return -1;

    hello->header.type = AODV_HELLO;
    hello->lifetime = lifetime;

    return 0;
}

// 解析Hello数据包
int parse_hello_packet(const void *buffer, int len, aodv_hello *hello) {
    if (!buffer || !hello || len < sizeof(aodv_hello)) return -1;

    int offset = 0;
    deserialize(&hello->header.type, buffer, sizeof(aodv_msg_type), &offset);
    if (hello->header.type != AODV_HELLO) return -1; // 类型不匹配

    deserialize(&hello->lifetime, buffer, sizeof(uint32_t), &offset);

    return 0;
}

// 构建数据包
int build_data_packet(aodv_data_packet *data_pkt, uint32_t payload_len, const char *payload) {
    if (!data_pkt || !payload || payload_len > MAX_PAYLOAD_SIZE) return -1;

    data_pkt->header.type = AODV_DATA;
    data_pkt->payload_len = payload_len;
    memcpy(data_pkt->payload, payload, payload_len);

    return 0;
}

// 解析数据包
int parse_data_packet(const void *buffer, int len, aodv_data_packet *data_pkt) {
    if (!buffer || !data_pkt || len < sizeof(aodv_header) + sizeof(uint32_t)) return -1;

    int offset = 0;
    deserialize(&data_pkt->header.type, buffer, sizeof(aodv_msg_type), &offset);
    if (data_pkt->header.type != AODV_DATA) return -1; // 类型不匹配

    deserialize(&data_pkt->payload_len, buffer, sizeof(uint32_t), &offset);
    if (data_pkt->payload_len > MAX_PACKET_SIZE || len < sizeof(aodv_header) + sizeof(uint32_t) + data_pkt->payload_len) return -1;

    deserialize(data_pkt->payload, buffer, data_pkt->payload_len, &offset);

    return 0;
}